package com.tuo51.evaluate.service.impl;


import com.starinside.wp.foundation.exception.BusinessException;
import com.starinside.wp.foundation.query.base.PagerQuery;
import com.starinside.wp.repository.ChildrenRepository;

import com.tuo51.evaluate.domain.evaluatingV2.*;
import com.tuo51.evaluate.repositories.evaluatev2.*;
import com.tuo51.evaluate.service.EvaluateV2ConclusionService;
import com.tuo51.evaluate.service.EvaluateV2Service;
import com.tuo51.evaluate.vo.evaluate.*;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

import static com.starinside.wp.foundation.model.ErrorCode.EVALUATE_RECORD_NOT_EXIST;

@Service
@Slf4j
@CacheConfig(cacheNames = "EvaluateV2ServiceImpl")
public class EvaluateV2ServiceImpl implements EvaluateV2Service {

    @Autowired
    private EvaluateV2RecordRepository recordRepository;


    @Autowired
    private EvaluateV2DimensionRepository dimensionRepository;


    @Autowired
    private EvaluateV2ItemRepository itemRepository;


    @Autowired
    private EvaluateV2RecordDimensionScoreRepository dimensionScoreRepository;

    @Autowired
    private EvaluateV2DimensionRecommendTipsRepository tipsRepository;


    @Override
    public Page<WebEvaluateRecordListVo> getEvaluatePage(String[] childrenIds, PagerQuery query) {

        List<String> cs = null;

        Specification<EvaluateV2Record> specification = (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();


            if(childrenIds != null && childrenIds.length > 0){
                CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("childrenId").as(String.class));
                for (String id : childrenIds){
                    in.value(id);
                }
                predicates.add(criteriaBuilder.and(in));
            }

            predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("finished"), true)));
            predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("deleted"), false)));

            criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));

            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("created")));

            return criteriaQuery.getRestriction();
        };
        Pageable pageable = PageRequest.of(query.getPageNum(), query.getPageSize());
        Page<EvaluateV2Record> page = recordRepository.findAll(specification, pageable);
        List<WebEvaluateRecordListVo> voList = page.getContent().stream().map(o -> WebEvaluateRecordListVo.of(o)).collect(Collectors.toList());
        return new PageImpl<>(voList, pageable, page.getTotalElements());
    }

    @Override
    public EvaluateV2Record getEvaluateDetail(String evaluateId) {
        return getEvaluateDetailByIdAndStaffId(evaluateId, null, true, null);
    }

    private EvaluateV2Record getEvaluateDetailByIdAndStaffId(String evaluateId, String staffId, boolean withHightLevelInfo, String recommendChannel){
        EvaluateV2Record record = null;

        if(staffId == null){
            record = recordRepository.getOne(evaluateId);
        }else {
            record = recordRepository.getByIdAndCreateTeacherId(evaluateId, staffId);
        }

        if(record == null){
            throw new BusinessException(EVALUATE_RECORD_NOT_EXIST, "没有测评记录");
        }

        List<EvaluateV2RecordDimensionScore> dimensionScores = dimensionScoreRepository.findAllByRecordIdOrderByCreated(evaluateId);
        record.setDimensionScores(dimensionScores);

        //缓存维度
        if(withHightLevelInfo) {
            List<EvaluateV2Dimension> dimensions = dimensionRepository.findAllByDeletedOrderByCode(false);
            HashMap<String, EvaluateV2Dimension> mapping = new HashMap<>();
            dimensions.stream().forEach(p -> {
                mapping.put(p.getId(), p);
            });

            List<EvaluateV2Item> failedQuestionItems = itemRepository.findAllFailedQuestionItems(record.getId());
            if (failedQuestionItems != null && failedQuestionItems.size() > 0) {
                List<EvaluateV2ExtInfoVO> highLevelInfo = failedQuestionItems.stream()
                        .map(i -> EvaluateV2ExtInfoVO.of(i, mapping.get(i.getDimensionId())))
                        .collect(Collectors.toList());
                record.setHighLevelInfo(highLevelInfo);
            }

            if (StringUtils.isNotEmpty(recommendChannel)){
                //查询
                List<EvaluateV2ExtInfoVO> highLevelInfo = record.getHighLevelInfo();
                if (highLevelInfo != null && highLevelInfo.size() > 0){
                    for (EvaluateV2ExtInfoVO extInfo : highLevelInfo){
                        EvaluateV2DimensionRecommendTips tips =
                                tipsRepository.getFirstByChannelOrChannelIsNull(extInfo.getDimensionId(), extInfo.getMonth(), recommendChannel);
                        if (tips != null && StringUtils.isNotEmpty(tips.getUrl())) {
                            extInfo.setRecommendURL(tips.getUrl());
                            extInfo.setRecommendTips(null);
                        }
                    }
                }
            }
        }

        return record;
    }

}
